package com.gradledemo.shiro;

import com.gradledemo.entity.AdminAuth;
import com.gradledemo.entity.AdminUser;
import com.gradledemo.service.AdminAuthService;
import com.gradledemo.service.AdminUserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.web.context.ContextLoader;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/*
 * Copyright (c) 2010-2015 LiZaoNet Inc. (http://www.lizaonet.com).
 * license: http://www.lizaonet.com
 */

@Service
public class ShiroDbRealm extends AuthorizingRealm {
    /**
     * 角色在 Session 中的 Key。
     */
    public static final String ROLE_KEY = "role";

    /**
     * 管理员角色
     */
    public static final String ROLE_ADMIN = "admin";
    /**
     * 前台用户角色
     */
    public static final String ROLE_FRONT_USER = "frontUser";
    /**
     * 管理员是否登录
     */
    public static final String ADMIN_IS_LOGIN = "adminIsLogin";
    /**
     * 前台用户是否登录
     */
    public static final String FRONT_IS_LOGIN = "frontIsLogin";
    /**
     * session 中的前台用户名称
     */
    public static final String SESSION_FRONT_USER_NAME = "frontUserName";
    /**
     * session 中管理员用户名称
     */
    public static final String SESSION_ADMIN_USER_NAME = "adminUserName";
    @Autowired
    private AdminUserService adminUserService;
    @Autowired
    private AdminAuthService adminAuthService;

    /**
     * 获得用户权限
     *
     * @param principals
     * @return
     */
    protected AuthorizationInfo doGetAuthorizationInfo(
            PrincipalCollection principals) {
        this.adminUserService = ContextLoader.getCurrentWebApplicationContext().getBean(AdminUserService.class);
        this.adminAuthService = ContextLoader.getCurrentWebApplicationContext().getBean(AdminAuthService.class);

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //获取当前登录的用户名
        String account = (String) super.getAvailablePrincipal(principals);

        List<String> permissions = new ArrayList<>();
        if (hasRole(ROLE_ADMIN)) {
            AdminUser adminUser = adminUserService.getInfoByName(account);
            if (adminUser != null) {
                List<AdminAuth> permission = adminAuthService.getAdminAuthByAdminId(adminUser.getAdminId());
                for (AdminAuth auth : permission) {
                    permissions.add(auth.getAuthVal());
                }
            } else {
                throw new AuthorizationException();
            }
        } else if (hasRole(ROLE_FRONT_USER)) {

        }
        if (permissions.size() > 0) {
            //给当前用户设置权限
            info.addStringPermissions(permissions);
        } else {
            info = null;
        }
        return info;

    }

    /**
     * 验证用户是否具备某角色。
     *
     * @param role 角色名称
     * @return 用户是否具备某角色
     */
    public boolean hasRole(String role) {
        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession();
        return session != null && role.equals(session.getAttribute(ROLE_KEY));
    }


    /**
     * 认证回调函数,登录时调用.
     *
     * @param authcToken 认识 Token 对象
     * @return 账号存在，返回
     * @throws org.apache.shiro.authc.AuthenticationException
     */
    protected AuthenticationInfo doGetAuthenticationInfo(
            AuthenticationToken authcToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
        this.adminUserService = ContextLoader.getCurrentWebApplicationContext().getBean(AdminUserService.class);
        AdminUser adminUser = adminUserService.getInfoByName(token.getUsername());
        if (adminUser != null) {
            return new SimpleAuthenticationInfo(adminUser.getAdminName(), adminUser.getPsw(), adminUser.getAdminName());
        }
        return null;
    }
}

